package cn.gemiman.daoyi.module.cms.service.appsitefootprint;

import cn.gemiman.daoyi.framework.common.enums.FootprintTypeEnum;
import cn.gemiman.daoyi.framework.common.enums.UserTypeEnum;
import cn.gemiman.daoyi.framework.common.pojo.PageResult;
import cn.gemiman.daoyi.framework.common.util.object.BeanUtils;
import cn.gemiman.daoyi.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.gemiman.daoyi.module.cms.controller.admin.appsitefootprint.vo.AppSiteFootprintPageReqVO;
import cn.gemiman.daoyi.module.cms.controller.admin.appsitefootprint.vo.AppSiteFootprintSaveReqVO;
import cn.gemiman.daoyi.module.cms.dal.dataobject.appsitefootprint.AppSiteFootprintDO;
import cn.gemiman.daoyi.module.cms.dal.mysql.appsitecomment.AppSiteCommentMapper;
import cn.gemiman.daoyi.module.cms.dal.mysql.appsitefootprint.AppSiteFootprintMapper;
import cn.gemiman.daoyi.module.cms.dal.mysql.articledetail.ArticleDetailMapper;
import cn.gemiman.daoyi.module.cms.dal.mysql.blogmessage.BlogMessageMapper;
import cn.gemiman.daoyi.module.cms.dal.mysql.blogtalk.BlogTalkMapper;
import cn.gemiman.daoyi.module.cms.vo.WithLikeBaseVO;
import cn.gemiman.daoyi.module.member.api.user.MemberUserApi;
import cn.gemiman.daoyi.module.member.api.user.dto.MemberUserRespDTO;
import cn.gemiman.daoyi.module.system.api.user.AdminUserApi;
import cn.gemiman.daoyi.module.system.api.user.dto.AdminUserRespDTO;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static cn.gemiman.daoyi.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.gemiman.daoyi.module.cms.enums.ErrorCodeConstants.APP_SITE_FOOTPRINT_NOT_EXISTS;

/**
 * 站点足迹 Service 实现类
 *
 * @author 道一源码
 */
@Service
@Validated
public class AppSiteFootprintServiceImpl implements AppSiteFootprintService {

    @Resource
    private AppSiteFootprintMapper appSiteFootprintMapper;
    @Resource
    private MemberUserApi memberUserApi;
    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private ArticleDetailMapper articleDetailMapper;
    @Resource
    private AppSiteCommentMapper appSiteCommentMapper;
    @Resource
    private BlogTalkMapper blogTalkMapper;
    @Resource
    private BlogMessageMapper blogMessageMapper;

    @Override
    public Long addFootprint(AppSiteFootprintSaveReqVO createReqVO) {
        AppSiteFootprintDO existDO = appSiteFootprintMapper.selectOne(new LambdaQueryWrapperX<AppSiteFootprintDO>()
                .eqIfPresent(AppSiteFootprintDO::getUserType, createReqVO.getUserType())
                .eqIfPresent(AppSiteFootprintDO::getUserId, createReqVO.getUserId())
                .eqIfPresent(AppSiteFootprintDO::getAppSiteId, createReqVO.getAppSiteId())
                .eqIfPresent(AppSiteFootprintDO::getAppId, createReqVO.getAppId())
                .eqIfPresent(AppSiteFootprintDO::getCategoryId, createReqVO.getCategoryId())
                .eqIfPresent(AppSiteFootprintDO::getArticleId, createReqVO.getArticleId())
                .eqIfPresent(AppSiteFootprintDO::getTalkId, createReqVO.getTalkId())
                .eqIfPresent(AppSiteFootprintDO::getMessageId, createReqVO.getMessageId())
                .eqIfPresent(AppSiteFootprintDO::getCommentId, createReqVO.getCommentId())
                .eqIfPresent(AppSiteFootprintDO::getFootprintFor, createReqVO.getFootprintFor()), false);
        if (FootprintTypeEnum.LIKE.getValue().equals(createReqVO.getFootprint())) {
            if (null != createReqVO.getArticleId()) {
                articleDetailMapper.updateThumbsUpTimes(createReqVO.getArticleId());
            }
            if (null != createReqVO.getCommentId()) {
                appSiteCommentMapper.updateThumbsUpTimes(createReqVO.getCommentId());
            }
            if (null != createReqVO.getTalkId()) {
                blogTalkMapper.updateThumbsUpTimes(createReqVO.getTalkId());
            }
            if (null != createReqVO.getMessageId()) {
                blogMessageMapper.updateThumbsUpTimes(createReqVO.getMessageId());
            }
        }
        if (null == existDO) {
            return createAppSiteFootprint(createReqVO);
        } else {
            AppSiteFootprintSaveReqVO updateReqVO = BeanUtils.toBean(existDO, AppSiteFootprintSaveReqVO.class)
                    .setFootprint(createReqVO.getFootprint());
            this.updateAppSiteFootprint(updateReqVO);
            return existDO.getId();
        }
    }

    @Override
    public Long createAppSiteFootprint(AppSiteFootprintSaveReqVO createReqVO) {
        // 插入
        AppSiteFootprintDO appSiteFootprint = BeanUtils.toBean(createReqVO, AppSiteFootprintDO.class);
        if (null != appSiteFootprint.getUserId() && null != appSiteFootprint.getUserType()) {
            if (UserTypeEnum.MEMBER.getValue().equals(appSiteFootprint.getUserType())) {
                MemberUserRespDTO checkedData = memberUserApi.getUser(appSiteFootprint.getUserId()).getCheckedData();
                appSiteFootprint.setUserNickname(checkedData.getNickname());
                appSiteFootprint.setUserAvatar(checkedData.getAvatar());
            } else if (UserTypeEnum.ADMIN.getValue().equals(appSiteFootprint.getUserType())) {
                AdminUserRespDTO checkedData = adminUserApi.getUser(appSiteFootprint.getUserId()).getCheckedData();
                appSiteFootprint.setUserNickname(checkedData.getNickname());
                appSiteFootprint.setUserAvatar(checkedData.getAvatar());
            }
        }
        appSiteFootprintMapper.insert(appSiteFootprint);
        // 返回
        return appSiteFootprint.getId();
    }

    @Override
    public void updateAppSiteFootprint(AppSiteFootprintSaveReqVO updateReqVO) {
        // 校验存在
        validateAppSiteFootprintExists(updateReqVO.getId());
        // 更新
        AppSiteFootprintDO updateObj = BeanUtils.toBean(updateReqVO, AppSiteFootprintDO.class);
        appSiteFootprintMapper.updateById(updateObj);
    }

    @Override
    public void deleteAppSiteFootprint(Long id) {
        // 校验存在
        validateAppSiteFootprintExists(id);
        // 删除
        appSiteFootprintMapper.deleteById(id);
    }

    private void validateAppSiteFootprintExists(Long id) {
        if (appSiteFootprintMapper.selectById(id) == null) {
            throw exception(APP_SITE_FOOTPRINT_NOT_EXISTS);
        }
    }

    @Override
    public AppSiteFootprintDO getAppSiteFootprint(Long id) {
        return appSiteFootprintMapper.selectById(id);
    }

    @Override
    public PageResult<AppSiteFootprintDO> getAppSiteFootprintPage(AppSiteFootprintPageReqVO pageReqVO) {
        return appSiteFootprintMapper.selectPage(pageReqVO);
    }

    @Override
    public <T extends WithLikeBaseVO<Long>> void generatorIsLike(Integer userType, Long loginUserId, List<T> list, SFunction<AppSiteFootprintDO, Long> column) {
        if (null != userType && null != loginUserId && CollUtil.isNotEmpty(list)) {
            Set<Long> collect = appSiteFootprintMapper.selectList(new LambdaQueryWrapperX<AppSiteFootprintDO>()
                    .eq(AppSiteFootprintDO::getUserId, loginUserId)
                    .eq(AppSiteFootprintDO::getUserType, userType)
                    .eq(AppSiteFootprintDO::getFootprint, FootprintTypeEnum.LIKE.getValue())
                    .in(column, list.stream().map(T::getId).toList())
            ).stream().map(column).collect(Collectors.toSet());
            list.parallelStream().forEach(c -> c.setIsLike(collect.contains(c.getId())));
        }
    }
}
